#include<linux/module.h>
#include<linux/sched.h>
#include<linux/pid.h>
#include<linux/wait.h>
#include<linux/cpumask.h>
#include<linux/kthread.h>
MODULE_LICENSE("GPL");

static int cpu;
struct task_struct * old_thread;

int my_function(void *argc)
{
	int data=-1;
	cpumask_var_t mask;
	alloc_cpumask_var(&mask,GFP_KERNEL);
	cpumask_set_cpu(cpu,mask);
	printk("in the kernel thread function!\n");
	printk("the current pid is:%d\n",current->pid);
	data=set_cpus_allowed_ptr(old_thread,mask);

	printk("the return result of the set_cpus_allowed_prt is:%d\n",data);
	printk("out the kernel thread function\n");
	return 0;
}
static int __init set_cpus_allowed_ptr_init(void)
{
	struct task_struct *result;
	long result1;
	struct thread_info *info;
	wait_queue_head_t head;
	wait_queue_t data;
	printk("into set_cpus_allowed_ptr_init.\n");
	old_thread=current;
	info=current_thread_info();
	result=kthread_create_on_node(my_function,NULL,-1,"set_cpus_allowed_ptr");

	wake_up_process(result);

	cpu=(info->cpu == 0)?1:0;
	printk("the cpu of the current thread is:%d\n",info->cpu);
	init_waitqueue_head(&head);
	init_waitqueue_entry(&data,current);
	add_wait_queue(&head,&data);
	result1=schedule_timeout_uninterruptible(100);
	printk("the new cpu os the current thread is:%d\n",info->cpu);

	printk("the pid of new thread is:%d\n",result->pid);
	printk("the return result of the schedule_timeout_uninterruptible is:%ld\n",result1);

	printk("the current pid is:%d\n",current->pid);
	printk("out set_cpus_allowed_ptr_init.\n");
	return 0;
}
static void __exit set_cpus_allowed_ptr_exit(void)
{
	printk("Goodbye set_cpus_allowed_ptr.\n");
}
module_init(set_cpus_allowed_ptr_init);
module_exit(set_cpus_allowed_ptr_exit);
